package com.hyk.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
//声明切片组件
@Aspect
public class LogCut {

    //定义切入点，匹配方法规则定义 拦截com.hyk.aop 包下以及子包下所有类的所有方法
    @Pointcut(value = "execution(* com.hyk.aop..*.*(..))")
    public void cut(){

    }

    /*
     * 声明前置通知 并将通知应用到定义的切入点上
     * 目标类方法执行前，执行该通知
     * */
    @Before(value = "cut()")
    public void before() {
        System.out.println("------这是前置通知------");
    }

    /*声明返回通知 并将通知应用到切入点
     * 目标类方法执行完毕执行该通知
     */
    @AfterReturning(value = "cut()")
    public void afterReturning() {
        System.out.println("------这是返回通知------");
    }

    /**
     * 声明最终通知 并将通知应用到切入点上
     * 目标类方法执行过程中是否发生异常
     * 均会执行该通知 相当于异常中的 finally
     */
    @After(value = "cut()")
    public void after() {
        System.out.println("------这是最终通知------");
    }

    /**
     * 声明异常通知 并将通知应用到切入点上
     * 目标类方法执行时发生异常 执行该通知
     */
    @AfterThrowing(value = "cut()", throwing = "e")
    public void afterThrowing(Exception e) {
        System.out.println("异常通知....方法执行异常时执行:" + e);
    }

    /**
     * 声明环绕通知 并将通知应用到切入点上
     * 方法执行前后 通过环绕通知定义相应处理
     */
    @Around(value = "cut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("环绕前置...");
        System.out.println("环绕通知");
        //System.out.println(pjp.getTarget() + "--" + pjp.getSignature());
        Object result = pjp.proceed();//执行目标对象方法
        System.out.println("环绕后置..."); return result;
    }

}
